﻿using System.IO;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using Microsoft.Xna.Framework.Graphics;

namespace Babylon.Toolbox
{
    public static class ContentManager
    {
        public static Texture2D LoadTexture2D(GraphicsDevice device, BitmapSource imageSource, bool disableAlphaChannel)
        {          
            // Create texture
            int width = GetExponantOfTwo(imageSource.PixelWidth);
            int height = GetExponantOfTwo(imageSource.PixelHeight);
            Texture2D texture2D = new Texture2D(device, width, height, true,
                                      SurfaceFormat.Color);

            GenerateLevel(0, texture2D, imageSource, width, height, disableAlphaChannel);

            return texture2D;
        }

        public static Texture2D LoadTexture2D(GraphicsDevice device, Stream source, bool disableAlphaChannel)
        {
            // Getting uncompressed datas
            BitmapImage imageSource = new BitmapImage();
            imageSource.SetSource(source);
            return LoadTexture2D(device, imageSource, disableAlphaChannel);
        }

        static int GetExponantOfTwo(int value)
        {
            int count = 1;

            do
            {
                count *= 2;
            }
            while (count < value);

            if (count > 2048)
                count = 2048;

            return count;
        }

        static void GenerateLevel(int level, Texture2D texture2D, BitmapSource imageSource, int width, int height, bool disableAlphaChannel)
        {
            WriteableBitmap w = new WriteableBitmap(width, height);
            Image i = new Image { Source = imageSource, Width = width, Height = height, Stretch = Stretch.Fill };

            w.Render(i, null);
            w.Invalidate();

            // Inverting ARGB->ABGR
            int pixelsSize = w.PixelWidth * w.PixelHeight;
            int[] pixels = new int[pixelsSize];
            for (int index = 0; index < pixelsSize; index++)
            {
                int a = (w.Pixels[index] >> 24) & 0x000000FF;
                int r = (w.Pixels[index] >> 16) & 0x000000FF;
                int g = (w.Pixels[index] >> 8) & 0x000000FF;
                int b = (w.Pixels[index]) & 0x000000FF;

                if (disableAlphaChannel)
                    a = 255;

                pixels[index] = (a << 24) | (b << 16) | (g << 8) | r;
            }

            // Sending to texture
            texture2D.SetData(level, null, pixels, 0, pixelsSize);

            // Next level
            if (width == 1 || height == 1)
                return;
            GenerateLevel(level + 1, texture2D, imageSource, width / 2, height / 2, disableAlphaChannel);
        }
    }
}
